package oop.ex2.expression;

import oop.ex2.exceptions.EmptyExpression;
import oop.ex2.exceptions.ExpectedAtomicExpression;
import oop.ex2.exceptions.ExpectedBinaryOperation;
import oop.ex2.exceptions.TerminatingStringNotFound;
import oop.ex2.exceptions.TokenNotRecognized;
import oop.ex2.tokenizer.Tokenizer;

/**
 * This is the base class for all the nodes that represent a binary operator. All the
 * nodes of this type build their children in the following way:
 * Every binary operator has two children which must be atomic - i.e - they must resolve to numbers.
 * When a binary operator is encountered in the token sequence, the existing node is added
 * as a child to the operator. So the binary operator is in charge of searching for one more
 * atomic node and adding it as another child.
 * @author daniel_i_l
 *
 */
public abstract class BinaryOpNode extends ExpressionNode {
	private final static NodeType NODE_TYPE = NodeType.BINARY_OP;
	
	/**
	 * Build a binary operator using the matched string.
	 * @param matchedString The matched string that generated this node.
	 */
	public BinaryOpNode(String matchedString) {
		super(matchedString);
		_nodeType = NODE_TYPE;
	}

	@Override
	public void generateChildren(Tokenizer tokenizer)
			throws TokenNotRecognized, EmptyExpression,
			ExpectedAtomicExpression, ExpectedBinaryOperation, TerminatingStringNotFound {
		
		//For a binary node, we just advance one token and build it
		if (tokenizer.isEmpty())
			throw new EmptyExpression("A sequence cannot be empty");
		
		tokenizer.advance(NodeType.ATOM);
		ExpressionNode currentNode = tokenizer.getExpressionNode();
		addChild(currentNode);
		
		currentNode.generateChildren(tokenizer);
	}
}
